Skip to content

Added Mass Energy Inverter, and more block smear recipes. 添加了能质逆变器和新的方块涂抹配方,优化了存储系统 - #4399

Merged
QiuShui1012 merged 28 commits into
Anvil-Dev:dev/1.21/1.6from
PigeonNian:inverter/1.21/1.6
Aug 15, 2026
Merged

Added Mass Energy Inverter, and more block smear recipes. 添加了能质逆变器和新的方块涂抹配方,优化了存储系统#4399
QiuShui1012 merged 28 commits into
Anvil-Dev:dev/1.21/1.6from
PigeonNian:inverter/1.21/1.6

Conversation

@PigeonNian

@PigeonNian PigeonNian commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Pigeon_Nian added 7 commits August 14, 2026 15:29
- 新增倒置砂轮判定条件,包含多种砂轮朝下状态
- 支持使用倒置砂轮去蜡、去锈、去皮原木铜块等方块
- 编写对应的BlockSmearRecipe生成逻辑,自动生成相关配方
- 新增大量相应配方JSON及解锁Advancement数据
- 修正语言文件英文翻译错误与格式
- 将多个配方文件中属性 "facing" 修改为 "face"
- 统一所有相关配方的方位为 "ceiling"
- 确保配方中方位属性命名一致,避免解析错误
- 涉及多种铜制品及木材剥皮配方的属性更新
- 提升配方数据的准确性和规范性
- 修改倒置砂轮的状态属性由GrindstoneBlock.FACING改为GrindstoneBlock.FACE
- 使用AttachFace.CEILING替代Direction.DOWN以正确表示挂在方块下方的状态
- 更新相关注释,明确倒置砂轮用于去蜡、去锈、去皮的功能描述
- 新增对门方块(DoorBlock)的特殊渲染处理
- 针对门的上下半部分分别渲染以保证完整外观
- 调整门下半部分渲染位置以避免与上方物体重叠
- 抽取renderBlockState方法复用方块渲染逻辑
- 保留并调用现有的区块实体渲染机制
- 增加了对 DoorBlock 和 GrindstoneBlock 的导入支持
- 调整铁砧渲染组件的 y 轴偏移量从20改为40
- 根据是否为 DoorBlock 动态调整块渲染的偏移位置
- 修改多处渲染调用 y 坐标和纵向间距,使界面元素布局更合理
- 修复结果块渲染时若为门类方块时的偏移显示问题
- 新增 MassEnergyInverterBlock 及对应的 BlockEntity,实现方块形状和渲染
- 在 ModBlocks 和 ModBlockEntities 中注册能质逆变器相关对象
- 添加能质逆变器的多步骤程序处理配方及数据文件
- 支持多语言显示信息,更新英文和英文(美式)语言包
- 引入能质逆变器在星体锻造砧中的方块配方
- 支持方块可用镐子挖掘标签添加新方块
- 在质量注入行为中检测相邻能质逆变器,注入质量翻倍
- 在功能分组中添加该方块物品标签和显示名称
- 能质逆变器在每个刻tick时为邻近空间超压器注入质量
- 添加对应资源文件,包括模型、区块状态和掉落物品表
- 新增配方解锁条件与进度奖励相关数据文件
- 新增事件监听器处理砧库方块涂抹配方
- 将被处理方块的属性复制到结果方块,保证方块状态一致
- 通过属性遍历实现方块状态属性的安全复制
- 利用BlockCache缓存调整后的方块状态
- 添加辅助方法inheritProperties和inheritProperty提高代码复用性
@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

echo "=== base: spacetime_supercomputer procedural JSON 结构对比 ==="; curl -sL "https://raw.githubusercontent.com/Anvil-Dev/AnvilCraft/dev/1.21/1.6/src/generated/resources/data/anvilcraft/recipe/procedur...

Reason: Security scan — [HIGH] Pipe to interpreter: curl | python3: Command pipes output from 'curl' directly to interpreter 'python3'. Downloaded content will be executed without inspection.
Safer: tirith run https://raw.githubusercontent.com/Anvil-Dev/AnvilCraft/dev/1.21/1.6/src/generated/resources/data/anvilcraft/recipe/procedural_process/spacetime_supercomputer.json — or: vet https://raw.githubusercontent.com/Anvil-Dev/AnvilCraft/dev/1.21/1.6/src/generated/resources/data/anvilcraft/recipe/procedural_process/spacetime_supercomputer.json (https://getvet.sh); script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@PigeonNian
PigeonNian marked this pull request as draft August 14, 2026 11:45
@Gugle2308

Copy link
Copy Markdown
Collaborator

代码审查摘要 — PR #4399

操作: opened
范围: 189 个文件 (12 Java, 177 生成资源) / 5921 行 diff — 新增 175, 修改 14, 删除 0
功能: ① 能质逆变器 (resolves #4338) ② 方块涂抹配方 (resolves #4324) — 1.21.x 常规 feature PR,非 26.1 迁移,跳过迁移健康度检查


📋 声称验证表

声称 状态 对应文件
能质逆变器 #4338 MassEnergyInverterBlock, MassEnergyInverterBlockEntity, MassInjectBehavior, ModBlocks/ModBlockEntities/FunctionalBlocks, procedural_process/mass_energy_inverter.json
方块涂抹配方 #4324 BlockSmearRecipeLoader, InWorldRecipeEventListener, 84 个新配方 JSON (36 dewax + 27 deoxidize + 21 strip)

方块模型 models/block/mass_energy_inverter.json、纹理和 3 个 wip_display 模型已在 base 分支预置,资产衔接完整 ✅


🔴 关键

未发现编译级或明确逻辑错误。

⚠️ 警告

  1. MassInjectBehavior.java — 质量翻倍不消耗电力:翻倍效果只检查 hasAdjacentInverter(纯方块相邻判断),不检查逆变器的电网状态。而 1024/tick 的耗电只作用于较弱的主动效果(每 tick 注入 5 质量)。最强效果(铁砧注入翻倍,无上限)反而免费——建议改为查询邻接的 MassEnergyInverterBlockEntity 并校验 isGridWorking()(或至少 grid != null),否则 POWER_CONSUMPTION = 1024 的设计对主要效果形同虚设。请确认是否有意为之。

  2. MultiBlockRecipeLoader.java / celestial_forging_anvil.json — 多方块中的逆变器交互存疑:第 2 层中央从金块换成逆变器后,逆变器的两个机制在 CFA 结构内都无法触发

    • 每 tick 注入依赖水平相邻的 SpaceOvercompressor(结构中没有,四周是金块);
    • 翻倍依赖铁砧砸中压缩机(hitBlockPos 必须 instanceof SpaceOvercompressorBlockEntity,逆变器不是)。

    hasAdjacentInverter 只查水平方向,不查垂直(下方就是时空超算)。如果意图是"铁砧落在逆变器上"或"放大超算的质量注入",当前实现没有对应路径。另外该结构变更会使已有 CFA 建筑失效(中央金块不再匹配配方),需要玩家重建——建议在 PR 描述中注明。

  3. 语言文件缺失:新增方块只更新了 datagen 生成的 en_us.json/en_ud.json,11 个手写语言文件(zh_cnzh_twzh_hkzh_memelzhja_jpko_krde_defr_fres_esru_ru)均未添加 block.anvilcraft.mass_energy_inverter 条目。中文玩家会直接看到原始 key,作为中文社区的模组建议至少补 zh_cn.json(能质逆变器)。

💡 建议

  • MassEnergyInverterBlockEntity.java — tick 每 tick 对 4 个水平方向调用 level.getBlockEntity(),区块边界处可能强制加载邻块区块(getChunk 会 load)。可先用 getBlockState 快速判断压缩机方块类型(用 getStateis() 或 BE type 预检),或仅当邻块已加载时查询。
  • MassEnergyInverterBlock.java — 无 overload/switch 方块状态属性,无法显示过载状态(其他电力方块通常有);非阻塞。
  • InWorldRecipeEventListener.inheritSmearBlockState — 位置数学已验证正确(blockInputOffset=(0,-1,0)(0, inputs.size()-1, 0) = (0,-2,0) = blockOutputOffset,对 2 输入配方 inputPos == outputPos ✅),但逻辑依赖 lib 事件时序(事件触发时 level 中 inputPos 仍是原方块、cache 中 outputPos 已是结果态)。若时序不符,属性继承会静默失效为 no-op——建议实测去皮原木朝向、门半格/朝向保留是否生效。另该方法对 inputs.size() > 2 的配方会错位,建议加注释说明约束。
  • BlockSmearCategory.java / RenderSupport.java — JEI 左侧输入列会渲染全部 5 种砂轮变体(z = 25 - 10*i,i≥3 时 z 为负值),右侧铁砧 z 从 20 调到 80——建议截图确认布局不重叠、不超出绘制区域。
  • EOF 换行 — 177 个文件缺末尾换行(多为全新生成文件,datagen 常态);但 en_us.json/en_ud.json 是从"有换行"变为"无换行",datagen 输出前后不一致,建议确认非 datagen 配置被意外改动。

🟢 看起来不错

  • 方块涂抹配方体系完整:36 dewax(覆盖全部蜡化变体)+ 27 deoxidize(9 家族 × 3 阶段,getPrevious 对蜡化变体返回空,与 vanilla 行为一致,需先除蜡再除锈的链条设计合理)+ 21 strip(10 种木材 × 2 + 竹块),ID 采用 result_path + 后缀 无冲突,FACE=CEILING 谓词正确写入生成 JSON。
  • inheritSmearBlockState 属性继承实现:类型安全的泛型属性复制(isInstance + cast),门/原木/楼梯/台阶的朝向、半格、类型等属性在涂抹后得以保留——这是对旧行为(结果不继承输入方块状态)的正确修复,JEI 门方块渲染也同步处理了。
  • 逆变器 BE 符合 IPowerConsumer 契约getGrid/setGridgetCurrentLevelgetPosisGridWorking 守卫齐全,服务端 tick 双保险(block 层 + BE 层各查一次 isClientSide)。
  • 程序化配方遵循既有 .loop(3).multipleLoopFirstStep(...) 惯例(base 分支已有 4 处同类用法),IrradiatorType.MASS/ENERGYTRANSCENDIUM_NUGGET 引用均有既有先例。

🧪 测试建议

被测目标 推荐测试场景 优先级
MassEnergyInverterBlockEntity.tick 电网断开/接入切换时的注入启停;无邻接压缩机;1 个逆变器邻接 2+ 压缩机 🔴
MassInjectBehavior 翻倍路径 压缩机旁有/无逆变器、逆变器无电时翻倍是否应生效 🔴
inheritSmearBlockState 去皮原木 AXIS 保留、门 HALF/FACING 保留、stairs/slab TYPE+WATERLOGGED 保留 🔴
配方 datagen 84 个配方 JSON 的输入/结果引用完整性(datagen run 验证) 🟡

结论: COMMENT — 实现质量整体良好,两个核心功能的配方/逻辑/资源链路完整。无阻塞性 bug,但需要作者确认两点设计意图(翻倍是否应耗电、CFA 结构中逆变器的实际作用路径),并建议补充至少 zh_cn.json 翻译。若前两点为有意设计,补上翻译后即可合并。


由 Hermes Agent 审查

- 在CrateBlock中加入打开箱子的音效播放
- 在HyperdimensionStorageStationBlock中加入打开末影箱的音效
- 在LargeCrateBlock中加入打开箱子的音效播放
- 在ShulkerContainerBlock中加入打开潜影盒的音效播放
- 确保音效只在客户端播放以提升用户体验
@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'minecraft-mod-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

cd /tmp/tgt && B="17eae4dda955ffbdf2e056223c36d682eed92051"; echo "=== 分支上 addComponent 调用点 ==="; curl -sL "https://api.github.com/repos/Anvil-Dev/AnvilCraft/git/trees/$B?recursive=1" -o tree.json 2>/...

Reason: script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

验证完成。所有关键点已交叉确认。输出审查(draft 模式:仅报严重问题,comment 级别)。

代码审查摘要 — PR #4399(converted_to_draft)

操作: converted_to_draft(按 draft 模式仅报告关键问题,comment 级别)
范围: 189 个文件 / 5921 行 diff(12 Java,175 新增生成资源,0 删除)
功能: 能质逆变器(#4338)+ 方块涂抹配方扩展(#4324)— 声称验证 ✅ 均与 diff 对应

✅ 已验证正确的关键点

  • 逆变器双倍注质的几何正确MassInjectBehaviorhitBlockPosgetBlockEntity(hitBlockPos) 取的是同一位置(即压缩机本体,1.21 与 26.1 克隆均已确认),hasAdjacentInverter 检查的是压缩机的水平邻居,无误。
  • 电网注册无需手动 onLoad/setRemovedServerBlockEntityEventListenerinstanceof IPowerComponent 自动 addComponent/removeComponent(1.21 目标分支已确认),isGridWorking() = grid 非空且 PowerGrid.isWorking()
  • inheritSmearBlockState 时序与偏移均正确 — lib 源码确认 InWorldRecipeEventrecipe.assemble()(结果已写入 BlockCache)之后触发;getBlockInputOffset().subtract(0, size-1, 0) = (0,-2,0) 与框架谓词(input1/输出同位于 (0,-2,0))完全一致。门的双格问题由 BlockCache.setBlockDOUBLE_BLOCK_HALF 分支处理(两半都转换 + 延迟邻居更新),去锈/去蜡门不会出现半扇错位或掉落。
  • 资源无缺失models/block/mass_energy_inverter.jsonblock/wip_display/mass_energy_inverter_wip{,_2,_3}.json 已在目标分支存在(adjust models #4337 添加),displayedModels 复数 API 目标分支已有(builder 自动加 block/wip_display/ 前缀),registerModelsWithPathPrefix(event, "block/wip_display") 已注册。配方 ID(result_path + _dewax/_deoxidize/_strip)无冲突,生成资源(advancement/loot/tag/lang en_us/en_ud)完整。

⚠️ 需要确认的设计问题

  1. 双倍注质不检查逆变器供电状态(设计不一致)MassInjectBehavior 只要压缩机旁有逆变器方块就 mass *= 2,完全不看 isGridWorking();而逆变器自身的 tick 注质(5 质量/tick × 每相邻压缩机)要求 isGridWorking() + 1024 功率/tick。结果:未通电的逆变器可免费获得双倍效果。若被动加倍是有意设计请忽略;否则应在 hasAdjacentInverter 处(或调用处)同时校验相邻逆变器的电网状态。

  2. 天体锻造砧(CFA)多方块结构 breaking change — 金环层中心 gold_blockmass_energy_inverterMultiBlockRecipeLoader + 生成配方同步更新)。已建成的 CFA 全部失效,玩家需手动替换中心金块;且逆变器本身是程序化流程产物,形成新的依赖链。另外 F 位四面只有金块/上下层方块,逆变器的功能性效果(双倍/注质)在 CFA 结构内不生效,纯结构件——确认这是预期设计。

📋 声称验证表

声称 状态 对应内容
能质逆变器(#4338 MassEnergyInverterBlock/BE、MassInjectBehavior 加倍、程序化流程配方、JEI 展示、注册/创造栏/战利品
新方块涂抹配方(#4324 倒置砂轮去蜡/去锈/去皮(~140 配方+advancement)、状态继承、JEI 门渲染适配

结论: COMMENT

draft 阶段未发现阻塞性 bug(几何、时序、双格方块、资源完整性均验证无误)。两个设计问题(免电加倍、CFA 结构变更)建议在转 ready 前明确意图。zh_cn 等语言键未含新方块名,属 Weblate 同步流程,无需处理。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

cd /tmp/tgt && curl -sL "https://server.cjsah.net:1002/maven/dev/anvilcraft/lib/anvillib-neoforge-1.21.1/" | grep -oE "2\.0[^/]*/" | sort -u | tail -8; echo "=== 试下载 2.0.0+snapshot.506 主 jar ==="; cur...

Reason: script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

- 新增板条箱的合成配方,使用木板和树脂制作
- 新增大型板条箱多方块结构配方,包含漂洗木材和树脂块
- 为板条箱合成配方添加解锁条件(拥有木板和树脂)
- 添加相关advancement文件,支持配方解锁进度的存储与判断
- 完善多方块结构配方及解锁advancement文件配置
@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/new-block-recipe-pr-review.md in skill 'minecraft-mod-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

cd /tmp/tgt && python3 -c "
import zipfile
z=zipfile.ZipFile('anvillib-sources.jar')
for n in z.namelist(): print(n)
" 2>&1 | head -20

Reason: script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

cd /tmp && curl -sL "https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4338" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d['body'][:800])" 2>/dev/null || curl -sL "https://api....

Reason: Security scan — [HIGH] Pipe to interpreter: curl | python3: Command pipes output from 'curl' directly to interpreter 'python3'. Downloaded content will be executed without inspection.
Safer: tirith run https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4338 — or: vet https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4338 (https://getvet.sh); script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

所有验证完成。汇总关键事实后输出审查。

验证结论汇总

  • 目标分支 MC 1.21.1,CI(build + checkstyle)已通过 → API 层面无编译问题
  • injectMass(long)isGridWorking()BlockCache 双格方块处理、事件时序(assemble 后 / cache accept 前)全部确认安全
  • 配方数据:36 dewax + 27 deoxidize + 21 strip = 84 个 block_smear 配方,各配 1 个 advancement,无重复 ID
  • 发现 2 个值得注意的问题(每 tick 块更新包、倍率不检查电网状态)+ 若干建议

代码审查摘要 — PR #4399

操作: synchronize
范围: 193 个文件(16 Java、177 生成资源) / 6005 行 diff
分支: inverter/1.21/1.6dev/1.21/1.6(MC 1.21.1,CI build + checkstyle ✅)

📋 声称验证表

声称 状态 对应文件
#4338 能质逆变器 MassEnergyInverterBlock(+Entity), ModBlocks, ModBlockEntities, MassInjectBehavior, ProceduralProcessRecipeLoader, MultiBlockRecipeLoader, FunctionalBlocks, 资产/配方/loot/advancement/tag
#4324 新的方块涂抹配方 BlockSmearRecipeLoader(36 dewax + 27 deoxidize + 21 strip = 84 配方 + 84 advancement), InWorldRecipeEventListener(状态继承), BlockSmearCategory + RenderSupport(门渲染)

🔴 关键

无阻塞性问题。交叉验证均通过:

  • injectMass(long) 签名匹配;isGridWorking() 为 IPowerComponent default 方法
  • 电网注册:ServerBlockEntityEventListener所有 IPowerComponent 统一在 ServerLoad 时 PowerGrid.addComponent、ServerUnload 移除 → 新 BE 无需自注册
  • inheritSmearBlockState 时序正确:lib 管线为 matches → assemble(写缓存) → post InWorldRecipeEvent → cache.accept(落世界),事件中读世界(输入原状态)+ 写缓存(结果)均有效;BlockCache.setBlock 原生处理 DOUBLE_BLOCK_HALF(双格门自动补另一半),(0,-1,0)-(0,size-1,0)=(0,-2,0)blockOutputOffset 重合(原地替换)计算正确
  • 配方 ID 无重复;Java ↔ JSON(procedural/multiblock/block_smear)完全一致;门/台阶/原木属性继承修复同时惠及旧的蜂蜡涂抹配方

⚠️ 警告

  1. MassEnergyInverterBlockEntity.java — 每 tick 块更新包刷屏:BE tick 在电网工作时对每个相邻压缩机每 tickinjectMass(5),而压缩机 injectMass → setChanged() → sendBlockUpdated(1.21.1 第 70-76 行),即每台相邻压缩机每秒 20 个块更新包。建议按 N tick 累积后一次性注入(如每秒 1 次),或仅在 storedMass 显示值变化时发更新。
  2. MassInjectBehavior.java — 铁砧质量翻倍不检查逆变器电网状态hasAdjacentInverter 只查方块存在,未走 isGridWorking()(BE tick 却检查了)。未通电的逆变器也能让铁砧注入翻倍——请确认这是有意设计(被动增幅)还是应加电网判断,避免与 BE 行为语义不一致。

💡 建议

  • MassEnergyInverterBlockEntity.javaMASS_PER_TICK = 5 vs NEUTRONIUM_INGOT_MASS = 10_000_000:被动注入需约 27.7 小时/锭(4 台并联约 6.9 小时),相对 1024 功率/tick 的成本几乎可忽略;若目的是"主动产质量",建议调大数量级,确认数值意图。
  • InWorldRecipeEventListener.javasubtract(0, inputs.size()-1, 0) 隐含"输入方块沿 Y 向下连续堆叠"假设;当前 1-2 输入配方成立,未来若出现并排/异位输入的多输入涂抹配方,取"最下方输入"继承属性会错位,建议由配方结构推导继承源位置。
  • 手写语言文件src/main/resources/.../lang/ 下的 zh_cn/zh_hk/zh_tw/ja_jp/ru_ru/ko_kr/de_de/es_es/fr_fr/lzh/zh_meme 均缺 block.anvilcraft.mass_energy_inverter,仅生成的 en_us/en_ud 已更新;若 Weblate 同步不及时,中文玩家会看到原始 key(可后续由 Weblate PR 补齐)。

🟢 看起来不错

  • 门配方从"结果重置为默认状态"到"继承 FACING/OPEN/HINGE/POWERED/HALF",配合 BlockCache 双格处理与 JEI 门渲染(renderDoorBlock 下移半格拼接),双格方块方案考虑周全
  • 84 个涂抹配方覆盖 1.21.1 全部 9 类铜方块(含原版 1.21 新增的 copper_block/exposed_copper 系与蜡封变体)+ 21 个去皮配方,且输入统一为倒置砂轮谓词(含 4 种模组砂轮),数据生成无重复 ID
  • 逆变器接入天体巨构(CFC 中层中心位)、程序化合成配方(3 轮 MASS→ENERGY→超镝粒注入,与 JSON 逐字一致)、创造标签、loot/advancement/pickaxe tag 齐全
  • 4 个储物方块新增开启音效(BARREL/ENDER_CHEST/SHULKER_OPEN),客户端侧触发位置正确

结论: APPROVE — 功能完整、注册/序列化/配方链路自洽,两个警告(每 tick 更新包、翻倍不查电网)建议后续优化,不阻塞合并。

🧪 测试建议

被测目标 推荐测试场景 优先级
MassEnergyInverterBlockEntity.tick() 电网供电/断电切换时注入启停;相邻 0/1/4 台压缩机;tick 频率与块更新包数量 🟡
MassInjectBehavior.handle() 逆变器相邻(通电/断电)× 铁砧下落质量翻倍;mass=0 时行为不变 🟡
InWorldRecipeEventListener.inheritSmearBlockState() 门(上半/下半命中)、楼梯朝向、原木轴向、水logged 方块去蜡/去锈/去皮后属性保持 🔴
BlockSmearRecipeLoader 配方 ID 唯一性;waxed 与未 waxed 输入均生成正确方向的配方 🟢
celestial_forging_anvil 多方块 中心位放置逆变器后结构校验通过/移除后失效 🟢

由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/vanilla-api-version-verification.md in skill 'minecraft-mod-pr-review' (1 replacement). · Patched references/new-block-recipe-pr-review.md in skill 'minecraft-mod-pr-review' (1 replacement).

- 新增 ShulkerContainerUpgradeRecipe 及其配方列表
- 创建 ShulkerContainerUpgradeCategory,实现潜影盒升级配方的GUI展示
- 在 AnvilCraftJeiPlugin 中注册潜影盒升级配方类型、类别及催化剂
- 添加多语言支持条目包括英文和自定义语言
- 在GUI中呈现附带提示的物品栏和升级动画效果
@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

cd /tmp && unzip -o -q mc-1.21.1-client.jar "net/minecraft/world/level/block/WeatheringCopper.class" -d /tmp/mcj 2>/dev/null; javap -p -c /tmp/mcj/net/minecraft/world/level/block/WeatheringCopper.clas...

Reason: Security scan — [MEDIUM] Archive extraction to sensitive path: Archive command 'unzip' extracts to a potentially sensitive location

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

- 移除不符合条件的打开者UUID,避免无效玩家占用状态
- 改用玩家存活状态和交互距离判断过滤打开者
- 保持打开者列表与当前实际玩家状态一致
- 优化性能,减少不必要的集合构建和遍历操作
- 确保打开计数器与更新后的打开者列表同步
@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

curl -sL "https://api.github.com/repos/Anvil-Dev/AnvilCraft/pulls/4399" | python3 -c "
import json,sys
d=json.load(sys.stdin)
print('state:', d.get('state'))
print('merged:', d.get('merged'))
print('b...

Reason: Security scan — [HIGH] Pipe to interpreter: curl | python3: Command pipes output from 'curl' directly to interpreter 'python3'. Downloaded content will be executed without inspection.
Safer: tirith run https://api.github.com/repos/Anvil-Dev/AnvilCraft/pulls/4399 — or: vet https://api.github.com/repos/Anvil-Dev/AnvilCraft/pulls/4399 (https://getvet.sh); script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

cd /opt/data/workspace/AnvilCraft && echo "=== 分支 tip: crate.json / mass_energy_inverter 配方 ===" && git ls-tree -r FETCH_HEAD --name-only | grep -E "recipe/(crate|procedural_process/mass_energy_invert...

Reason: script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

审查完成,所有关键点均已交叉验证。输出审查意见:

代码审查摘要 — PR #4399

操作: synchronize
范围: 203 个文件(22 Java / 181 新增 / 0 删除),6498 行 diff
声明: 新增能质逆变器(#4338)+ 新方块涂抹配方(#4324),含一批同步过来的存储/配方改动

🔴 关键

未发现阻塞性问题。所有引用(ModBlocks.MASS_ENERGY_INVERTERRESIN_BLOCKLASER_RECEIVERWIP_BLOCK、4 种 Grindstone、JeiRenderHelper.getArrowOutputFromBelowBlockPredicateWithState.ofTagCube3x3PartHalf.MID_CENTER 等)在目标分支 dev/1.21/1.6 上均存在;wip_display/mass_energy_inverter_wip{,_2,_3} 模型已预存在于目标分支,无缺失模型。

⚠️ 警告

  • ShulkerContainerBlockEntity.recheckOpeners — 重构丢掉了旧的 hasContainerOpen() 检查。新逻辑只移除「离线/死亡/超范围」的玩家;若 GUI 通过异常路径关闭(RPC close 丢失、强制关闭等)而玩家仍存活且在范围内,openers 会残留该玩家 → openersCounter 计数恒 ≥1 → 箱盖永久保持打开,直到玩家离开范围。旧代码的 retainAll(nearbyOpeners)(含 hasContainerOpen 过滤)能自愈此场景。建议 removeIf 谓词补上 || !player.hasContainerOpen()(顺带说明:新写法确实修复了旧代码「范围内开任何容器都会撑住盖子」的怪癖,方向是对的)。
  • MassEnergyInverterBlockEntity.tick — 每 tick 对每个相邻超压器调用 injectMass(5),而 injectMasssetChanged()(被覆写为 sendBlockUpdated)→ 每 tick 发一次 BE 同步包(每个逆变器-超压器对 20 包/秒)。且 MASS_PER_TICK = 5 对比 NEUTRONIUM_INGOT_MASS = 10_000_000 几乎无意义(产 1 锭需约 200 万 tick ≈ 27.8 小时)。建议要么提高速率,要么节流同步(如仅在整秒 tick 同步)。
  • MassInjectBehavior ×2 不检查电网 — 铁砧注质翻倍只要求相邻存在逆变器方块(hasAdjacentInverter),不要求逆变器 isGridWorking();而 BE 自身的注质要求电网工作。若设计意图是「通电的逆变器放大质量」,×2 也应校验 isGridWorking(),否则与 BE 行为不一致(未通电逆变器白嫖翻倍)。
  • 生成文件尾换行风格不一致 — 181 个新增生成文件 + 修改的 en_us.json/en_ud.json 等全部缺失末尾换行,而目标分支既有 generated 文件均带尾换行(已抽查 waxed_copper_block.json)。请在本分支跑一遍 runData 确认输出可复现、与目标分支的 datagen 依赖版本一致,否则 CI 的生成物校验可能失败。

💡 建议

  • InWorldRecipeEventListener.inheritSmearBlockState — 逻辑经 AnvilLib 源码核验成立(InWorldRecipeManager.triggerassemble() 只写 BlockCache 模拟态 → 事件发布 → 之后才 context.accept() 落世界),inputPos == outputPos((0,-2,0))计算对标准 2 输入竖排涂抹布局正确,且能顺带修复旧蜜脾配方丢失楼梯朝向/门铰链等状态的问题。但它隐式依赖「事件先于世界变更」的时序和固定竖排布局,建议加注释说明该假设,防止 AnvilLib 时序变动后静默失效。
  • BlockSmearRecipeLoader — 全注册表遍历生成配方(BuiltInRegistries.BLOCK.holders())的 ID 方案 {result}_{suffix} 已验证与既有 waxed_* 命名无冲突(0 冲突),且 deoxidize 逐级(氧化→风化→暴露→普通)各自成配方、oxidized_* 只有 dewax 无 deoxidize——正确。若未来 mod 自身加入可剥/可氧化方块会自动纳入,注意保持生成确定性即可。

🟢 看起来不错

  • 能质逆变器完整闭环:方块/BE/注册/标签/战利品/模型/配方/创造页/天体巨构多方块(CFC 层)全部就位,POWER_CONSUMPTION=1024 与现有消费端量级(加速环 256、CFA 1000/4000)匹配。
  • 倒置砂轮配方(face: ceiling)序列化正确,涂抹结果状态继承(原木轴向、门朝向/铰链)经事件时序核验可正常工作。
  • 潜影集装箱升级 JEI 类别与目标分支 Upgrade2ShulkerContainerBehavior 实际机制一致(超压器 + 6 下界合金块 + 大板条箱 + 铁砧)。
  • en_us/en_ud/JeiLang 三个语言源 4 个新 key 完全对齐。
  • celestial_forging_anvil 多方块在中间层插入逆变器(CFC),生成的 JSON 与 builder 一致。

📋 声称验证表

声称 状态 对应文件
能质逆变器(#4338 MassEnergyInverterBlock(Entity), MassInjectBehavior, ProceduralProcessRecipeLoader, ModBlocks/ModBlockEntities/FunctionalBlocks, 天体巨构多方块变更
新方块涂抹配方(#4324 BlockSmearRecipeLoader(去蜡/去锈/去皮 3 类),InWorldRecipeEventListener 状态继承,BlockSmearCategory/RenderSupport 门渲染
(同步)板条箱/大板条箱配方 ShapedRecipeLoader.crate, MultiBlockRecipeLoader.large_crate
(同步)存储方块开合音效 CrateBlock/LargeCrateBlock/HyperdimensionStorageStationBlock/ShulkerContainerBlock(仅客户端)
(同步)潜影集装箱升级 JEI ShulkerContainerUpgradeCategory/Recipe, AnvilCraftJeiPlugin

结论: COMMENT — 两个 TODO issue 均已完整落地,未发现编译级或逻辑级关键缺陷;以上警告均为非阻塞改进项,建议作者确认生成文件换行风格与电网×2 的设计意图后再合并。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'minecraft-mod-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

cd /tmp && rm -rf anvillib_src && mkdir anvillib_src && tar -xzf anvillib-src.tar.gz -C anvillib_src 2>&1 | head -3; find anvillib_src -name "*.java" | head -10; echo "---"; grep -rln "setInputBlocks"...

Reason: recursive delete

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

- 在BreakBlock事件中增加判断,非Shift状态阻止破坏包含超过1000个物品的箱子
- 在AnvilHammer中添加限制,不允许锤子移除包含过多物品的储存箱
- 修改箱子破坏逻辑,使其触发掉落箱内所有物品及自身
- StorageBlockEntity新增获取总物品数量方法,支持数量检测
- StorageBlockEntity新增掉落容器内容及自身的方法,供破坏时调用
- 添加相关客户端提示:超过数量限制需按Shift破坏与锤子无法移除提示
- 计算空栏位数量以提升放置物品的准确性
- 引入辅助方法统计同类物品的堆叠剩余空间
- 限制提取数量不超过库存可用空间与储存最大数量
- 调整空栏位数量以正确反映堆叠溢出情况
- 修正提取逻辑避免过量取出资源
- 保持玩家背包和储存视图状态一致
@Gugle2308

Copy link
Copy Markdown
Collaborator

代码审查摘要 — PR #4399

操作: converted_to_draft
范围: 221 文件(38 Java,184 新增,0 删除)/ 8349 行 diff
分支: inverter/1.21/1.6 → dev/1.21/1.6(1.21.x 常规功能 PR,非 26.1 迁移)

概览

三大块变更:① 能质逆变器(新方块/BE + 天工砧结构加入 + 程序化配方);② 新方块涂抹配方(倒置砂轮去蜡/去锈/去皮,84 条生成配方);③ 存储系统重构(破坏行为、GUI 批量操作/撤销、自定义 loot、只读物品栏能力、tooltip)。生成数据与 loader 逻辑逐项吻合,datagen 已跑通;Java 无 TODO/FIXME/调试残留。以下为草稿阶段值得优先处理的问题。

🔴 关键

  • StorageBlockEntity.java(新增 dropContents — 删除 storage 后未调用同 PR 新增的 clearId()(该方法现在是死代码):Storages.remove(this.id)this.id 仍残留。与 ShulkerContainerBlock.playerWillDestroy(空容器时调 clearId())的处理不一致。目前板条箱掉落物默认不带 STORAGE 组件所以未显形,但 BE 上挂着已删除 storage 的悬垂 id,任何后续读取路径(loot 组件拷贝、RPC)都会拿到死引用。建议 dropContents 在 remove 后立即 clearId()

  • CrateBlock / LargeCrateBlock playerWillDestroy — 破坏行为回归:旧逻辑 creative 破坏会掉落带 storage 引用的容器物品(内容保留);新逻辑 dropContentscreative 同样倾倒全部内容并硬删除 storage,而 creative 又无方块掉落物(锤子路径 drops = List.of())——大板条箱 65536 格内容会全部变成地面实体(卡顿/超时消失风险),玩家拿不回容器。Shulker 容器和空间站都保留了 creative 特判(掉物品保留 storage),唯独板条箱没有。若"破坏即倾倒"是有意设计,请确认 creative 场景的处理方式。

⚠️ 警告

  • StorageServerStub.java StorageUsageValidator — 无访问控制:只校验 playerId 匹配,不校验玩家与 storage 的关联(对比 StorageAccessValidatorstillValid 8 格检查)。任何玩家可用任意 UUID 调用 getStorageUsage 枚举任意 storage 的类型列表/数量 → 信息泄露面。建议至少要求该 storage 与玩家可见的方块/物品关联(如按 sourcePos 校验)。

  • MassInjectBehavior.java — 铁砧注入质量翻倍只查相邻方块存在(hasAdjacentInverter),不查电网供电;而 MassEnergyInverterBlockEntity.tick 的被动注入要求 isGridWorking()。未接电的逆变器也能翻倍,两个机制判定条件不一致,请确认设计意图。

  • StorageServerStub.java undoGroup — 若 Shift 拖拽中途关闭 GUI/断线,endUndoGroup 丢失后 undoingGroup 一直为 true,期间所有存入操作会并入下一组撤销记录。建议在 stub 层加防呆(如 begin 后限定 tick 数超时自动 end)。

  • ShulkerContainerBlockEntity.java recheckOpeners — 重构后丢掉了 hasContainerOpen() 检查:范围内但已关闭 GUI 的玩家不再被移出 openers(旧代码会移除)。低影响但属行为变化,请确认。

  • ReadOnlyItemHandlerWrapper.java — 类注释是字面 ? 字符(/// ??? IItemHandler ????????????????),源文件编码损坏,请重写该注释。

  • AnvilHammerItem.java — LargeCrateBlock 的 >1000 守卫用 level.getBlockEntity(pos) 直查,其他路径(preventCrateBreak/playerWillDestroy)都用 getMainPartPos。若子方块无 BE,锤子专属提示会失效(BreakEvent 仍兜底拦截,仅提示文案不同),建议统一用 getMainPartPos

  • MultiBlockRecipeLoader.java — 天工砧结构加入 mass_energy_inverter 会使现存已搭建的砧失效需重建,确认发布说明有提示。

🟢 看起来不错

  • inheritSmearBlockState 属性继承机制验证通过:InWorldRecipeEvent 在 assemble() 之后、BlockCache.accept() 之前触发,此时世界仍持有原输入方块、cache 持有结果——从世界读原属性、改写 cache 的时序完全正确;AnvilLib BlockCache.setBlock 对门类方块会双半联动放置,门的朝向/开合/半格属性可正确继承,copper door 涂抹配方可行。
  • AnvilHammerItem 中把 playerWillDestroy 移到 dropSilkTouch 之前是有意且正确的重排(空潜影箱先 clearId() 再走 loot 拷贝,避免悬垂引用)。
  • StorageScreen 新交互(Shift 拖拽批量入仓、Alt 同类移入、Ctrl+Z 撤销、中键克隆拖拽)结构清晰:撤销记录按类型合并、上限 4 条、拖拽用 begin/endUndoGroup 合并成单条。
  • 自定义 loot(shulker/空间站拷贝 STORAGE 组件 + 主方块状态条件)正确;ReadOnlyItemHandlerWrapper 语义正确(insert 原样返回/extract 空/校验 false)。
  • 禁止非 Shift 破坏 >1000 物品板条箱的守卫与 tooltip 文案(break_requires_shift / hammer_break_denied)配套完整。

📋 声称验证表

声称 状态 对应实现
resolved #4338 能质逆变器 MassEnergyInverterBlock/BE、ModBlocks/ModBlockEntities 注册、程序化配方、天工砧结构 F 符号
resolved #4324 新方块涂抹配方 BlockSmearRecipeLoader(砂轮去蜡/去锈/去皮)+ 84 生成配方 + JEI 分类 + 属性继承
fixed #4403 破坏存储方块丢失内容物 ✅(建议按上方关键项收尾) dropContents 倾倒 + 破坏保护 + shulker/空间站自定义 loot 保留 storage
resolved #4408 存储 GUI 物品栏优化 Shift 拖拽/Alt 同类/Ctrl+Z 撤销/中键克隆/数量 tooltip

结论: COMMENT

草稿阶段不阻塞合并,但建议在转 ready 前处理:🔴 两项(dropContentsclearId();确认 creative 破坏板条箱行为)+ ⚠️ 中 StorageUsageValidator 权限校验与逆变器翻倍供电判定。其余为健壮性/一致性建议。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'anvilcraft-power-storage-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

for p in "assets/anvilcraft/textures/block/mass_energy_inverter_side.png" "assets/anvilcraft/textures/block/mass_energy_inverter_top.png"; do code=$(curl -s -o /dev/null -w "%{http_code}" --max-time 1...

Reason: Security scan — [HIGH] Pipe to interpreter: curl | python3: Command pipes output from 'curl' directly to interpreter 'python3'. Downloaded content will be executed without inspection.
Safer: tirith run https://api.github.com/repos/Anvil-Dev/AnvilCraft/commits?path=src/main/resources/assets/anvilcraft/models/block/mass_energy_inverter.json&sha=dev/1.21/1.6&per_page=3 — or: vet https://api.github.com/repos/Anvil-Dev/AnvilCraft/commits?path=src/main/resources/assets/anvilcraft/models/block/mass_energy_inverter.json&sha=dev/1.21/1.6&per_page=3 (https://getvet.sh); script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

分析完成。以下是审查意见:


代码审查摘要 — PR #4399

操作: edited
范围: 221 个文件 (38 Java, 184 新增, 0 删除) / 8349 行 diff
内容: 能质逆变器(新方块+电网用电器+合成链)、倒置砂轮 block_smear 配方(去蜡/去锈/去皮)、存储系统大改(撤销、批量快捷移动、战利品表保存 STORAGE 组件、板条箱防误拆、潜影集装箱升级)、修复若干存储 bug

🔴 关键

未发现必须阻塞合并的问题。以下 ⚠️ 建议在合并前确认/修复。

⚠️ 警告

  1. MassInjectBehavior 翻倍不检查电网状态hasAdjacentInverter() 只判断相邻方块存在,无电的逆变器也能让铁砧质量注入 ×2;而主动注入(MassEnergyInverterBlockEntity.tick)要求 isGridWorking()。两条路径的生效条件不一致。若"通电才增强"是设计意图,应加 isGridWorking() 检查;若是有意为之(被动增幅),建议在物品 tooltip 中说明。
  2. undo 分组泄漏beginUndoGroup 后若玩家中途关闭界面(Esc 不触发 mouseReleasedendUndoGroup),undoingGroup 保持 true。之后一次普通 deposit/moveSame 会被并入 undoGroup 且不 push;下次 shift 拖拽的 beginUndoGroup 会直接清空它 → 那笔操作永久丢失撤销记录(物品不丢,只是无法 Ctrl+Z)。建议在 StorageScreen.onClose() 补发 endUndoGroup
  3. getStorageUsage 无访问控制StorageUsageValidator 只校验玩家身份,不校验 storageId 是否属于该玩家可访问的存储。任何拿到他人存储 UUID 的玩家都能枚举其内容类型。建议与 StorageAccessValidator 对齐(校验对应方块已加载且在访问范围)。
  4. 新中文翻译缺失zh_cn.json(main/resources)未更新:block.anvilcraft.mass_energy_inverter、全部 crate/shulker tooltip、JEI 分类、storage.countbreak_requires_shift 等新键无中文,中文玩家会看到英文回退。该 mod 主要受众是中文玩家,建议补齐。
  5. ReadOnlyItemHandlerWrapper.java 注释乱码/// ??? IItemHandler ???????????????? 是损坏的 UTF-8 注释(已从 diff 确认是文件内真实内容),建议修复。
  6. 撤销覆盖不一致 — Shift+点击(空手持)走新批量路径可撤销;Shift+点击(手持物品)走 interact 的 QUICK_MOVE_TO_STORAGE 单槽路径不记录 undo。同一手势两种撤销行为。

💡 建议

  • ItemTooltipManagerSTORAGE_USAGE 缓存永不清理,客户端内存随触碰过的存储数量无界增长(量小但建议加容量上限)。
  • getTotalCount() 每次破坏尝试全量遍历槽位(潜影集装箱上限 65536 类型),大存储下是 65k 次迭代;可接受但可缓存。
  • HyperdimensionStorageStationBlock.playerWillDestroy 缺少空存储时 clearId() 的处理,与 ShulkerContainerBlock 行为不一致(空站拆除后物品残留悬空 storage ref)。
  • 逆变器主动注入 5 质量/tick,相对中子锭(10,000,000 质量)约 27 小时/锭,确认数值设计是否符合预期。
  • 新 Java 文件(MassEnergyInverterBlock.javaMassEnergyInverterBlockEntity.java)缺文件尾换行;183 个生成 JSON 无尾换行(数据生成器产物,数量未超阈值,可忽略)。
  • MassEnergyInverterBlockEntity 无序列化字段、grid@Getter @Setter,与 PowerConverterBlockEntity 的电网组件模式一致 ✓。

🟢 看起来不错

  • recheckOpeners 是真正的修复StorageScreen 是 RPC 驱动、无 ContainerMenu,player.hasContainerOpen() 恒为 false——旧代码 retainAll 会把所有 openers 清空,导致关闭路径 openers.remove() 返回 false 不 decrement、方块卡在 opened 状态。新代码按 null/死亡/超距清理,正确。
  • 撤销系统实现干净Deque<UndoRecord> + MAX_UNDO_RECORDS=4 + 分组合并;undoplayer.addItem 部分成功时 ItemStack 会被原地缩减、剩余量重新 insert,无复制/吞物品风险。
  • 战利品表:main-part 条件与旧 FlexibleMultiPartBlock::loot 结构一致(子部件破坏不掉落的既有行为未变),新增 copy_components(STORAGE) 正确;AnvilHammerItemplayerWillDestroy 提前到 dropSilkTouch 之前,确保空存储 clearId() 后 loot 复制的是清空后的组件。
  • inheritSmearBlockState:为涂抹结果继承输入方块状态(门朝向/原木轴/铜灯泡 LIT),是配方系统缺失的必要补丁;inheritProperties 按共有属性复制,安全。
  • 新 block_smear 配方 JSON 与 loader 完全一致(倒置砂轮 5 种 + 目标块 → 结果);celestial_forging_anvil 多方块配方已同步重生成。
  • 渲染顺序修复(高亮→物品→tooltip,手持物品 z=100)与门方块的 JEI 双格渲染处理得当。
  • 方块模型/纹理/3 个 WIP 显示模型已在 base 分支备齐(已实测 200),新方块不会缺模型。

📋 声称验证表

声称 状态 对应文件
resolved #4338 / #4324 ⚠️ 无法直接核对 issue 内容(API 超时) 存储修复集(recheckOpeners、preventCrateBreak、loot copy_components、dropContents)与描述相符
能质逆变器 MassEnergyInverterBlock/BlockEntity, MassInjectBehavior, ModBlocks/ModBlockEntities, ProceduralProcessRecipeLoader, 模型/语言/战利品表
方块涂抹配方 BlockSmearRecipeLoader (+~120 生成 JSON), InWorldRecipeEventListener, BlockSmearCategory
优化存储系统 StorageServerStub(undo/批量/克隆), StorageScreen, ItemTooltipManager, StorageTooltip 系, ReadOnlyItemHandlerWrapper, ShulkerContainerUpgrade*

🧪 测试建议

被测目标 推荐测试场景 优先级
MassEnergyInverterBlockEntity.tick 电网过载停止注入;4 方向多压缩机;逆变器被破坏后注入停止 🔴
StorageServerStub.undo 背包满/部分成功;连续 5 次操作后最旧记录被挤出;undo 组中途中断 🟡
ShulkerContainerBlockEntity.recheckOpeners 打开→关闭;登出;传送离开;生存拆子部件 🟡
BreakBlockEventListener.preventCrateBreak 阈值边界 1000/1001;Shift 绕过;锤子拒绝路径 🟡
InWorldRecipeEventListener.inheritSmearBlockState 门/活板门/原木/铜灯泡去蜡去锈后的属性保留 🟢

结论: COMMENT — 核心逻辑(存储修复、逆变器、涂抹配方)质量良好,无阻塞性问题;建议合并前确认 ⚠️ 1-3(翻倍无电检查、undo 组泄漏、翻译缺失),其余可按后续 PR 跟进。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

cd /tmp && for repo in "Anvil-Dev/anvillib" "Anvil-Dev/AnvilCraftLib" "Anvil-Dev/lib"; do url="https://raw.githubusercontent.com/$repo/1.21.1/anvillib-recipe/src/main/java/dev/anvilcraft/lib/v2/recipe...

Reason: Security scan — [MEDIUM] Lookalike TLD detected: Domain uses '.dev' TLD which can be confused with file extensions

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/storage-feature-pr-review-patterns.md in skill 'minecraft-mod-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

分析完成。所有关键点已核实(含在 PR 分支与 dev/1.21/1.6 目标分支上的交叉验证)。输出审查意见:


代码审查摘要 — PR #4399

操作: synchronize
范围: 221 个文件(38 Java / 184 新增、0 删除)/ 8384 行 diff
分支: inverter/1.21/1.6 → dev/1.21/1.6(1.21 线,非 26.1 迁移,跳过 API 迁移检查)

🔴 关键

  • 生成的 en_us.json / en_ud.json 过期,4 个新 lang key 缺失ScreenLang / ScreenTooltipLang 中已添加 tooltip.anvilcraft.storage.typestooltip.anvilcraft.storage.types.valuescreen.anvilcraft.tooltip.crate.break_requires_shiftscreen.anvilcraft.tooltip.crate.hammer_break_denied,但生成文件里没有(en_us 只新增了 5 个 key,en_ud 只有 1 个)。运行时会直接显示原始 key:板条箱 >1000 件拒拆提示、锤子拒拆提示、存储 tooltip 的 "Types:" 行全部中招。已核对 dev/1.21/1.6 上这 4 个 key 不存在,属本 PR 新增但未重新跑 datagen。请重新运行 runData 并提交生成的 lang 文件。

⚠️ 警告

  • ReadOnlyItemHandlerWrapper.java 注释乱码已入库 — 文件里是字面 /// ??? IItemHandler ????????????????(od 确认是 ? 字符而非显示问题),全 PR 唯一一处编码损坏,疑似作者编辑器编码转换导致。功能无害但应修复,并留意提交管线编码设置。
  • HyperdimensionStorageStationBlock.playerWillDestroy 缺少空容器处理 — 与 ShulkerContainerBlock(空则 clearId())不一致:空的高维存储站拆除后仍掉落带 STORAGE 引用的物品,且空 storage 记录在 Storages 保存数据中永不清理(潜影集装箱 clearId 也只清 BE 引用、不删记录,同一问题)。长时间游玩会积累空记录,建议拆空时删除对应记录。
  • StorageBlockEntity.dropContents() 逐 64 拆分生成 ItemEntity — 大板条箱上限 65536 时一次拆除可产生上千实体,瞬间卡顿/实体挤压。>1000 保护只拦玩家手拆,锤子/爆炸路径无此限制。建议限制单次实体数或分批生成。
  • AnvilHammerItem.breakBlock 的 crate 保护用 level.getBlockEntity(pos) 直接取 BE — 大型板条箱子方块位置无 BE,锤子保护检查会跳过子方块(实际仍会被 preventCrateBreak 事件兜底拦截,但该事件内用 getMainPartPos 逻辑不一致),建议统一。
  • ItemTooltipManager 三个静态 Map(STORAGE_USAGE/TIMES/PENDING)永不清理 — 客户端每个见过的 storage UUID 永久占一条,长会话内存缓慢增长,建议加容量上限或随容器销毁清理。

💡 建议

  • inheritSmearBlockState 依赖 anvillib 事件时序 — 逻辑成立的前提是 InWorldRecipeEvent 在配方结果写入 BlockCache 之后、flush 之前触发(cache.getBlockState(outputPos) 能拿到待应用结果)。若 lib 触发顺序相反,属性继承会静默失效(setBlock 回写旧方块)。建议实测一次门/原木的去蜡、去皮确认朝向保持。若已验证可忽略。
  • undo()emptySlots 是估算值 — 与真实 addItem 结果可能有偏差,但 addItem 失败会把余量回插 storage,不会丢物品,逻辑安全;可简化。
  • beginUndoGroup/endUndoGroup 无 try/finally — 拖拽中途断线/关 GUI 时服务端 stub 停留在 undoingGroup=true,后续 deposit 会合并成一条 undo 记录,直到下次 beginUndoGroup 重置(自愈,非阻塞)。
  • 爆炸/激光/活塞破坏板条箱仍会丢内容 — 不走 playerWillDestroy,storage 记录成为孤儿(改动前亦然,非回归),可在 setRemoved 兜底。
  • 183 个生成文件 + 4 个新 Java 文件缺尾换行 — base 现有生成文件均以 \n 结尾,建议统一避免后续 diff 噪声。

🟢 看起来不错

  • 存储数据保留修复设计清晰:潜影集装箱/高维站走战利品表 copy_components(携带数据掉落)、板条箱走 dropContents(倾倒内容),行为区分明确,与 tooltip 文案一致。
  • AnvilHammerItem 交换 playerWillDestroydropSilkTouch 顺序正确 — 保证空潜影集装箱 clearId 先于战利品生成,避免掉落含陈旧引用的物品。
  • recheckOpeners 重构(全量玩家扫描 → removeIf 现有集合) 修复了相邻容器互相"误算打开"的问题,方向正确。
  • 撤销系统实现完整:undo 记录上限 4、分组合并、moveInventoryStackToStorage 改返回插入数量,客户端 Ctrl+Z / Shift 拖拽多选 / Alt 同类快移 / 创造中键克隆拖放交互齐全,RPC validator 覆盖到位。
  • 能质逆变器isGridWorking() 为 IPowerConsumer 默认方法(Optional 空安全),injectMass(long) 签名匹配;合成链路(激光辐照 WIP → 注入超然锭 → 循环 3 次)与 celestial_forging_anvil 多方块整合、JEI 展示、创意标签、战利品表、blockstate/模型(手工模型在 src/main/resources,base 已有)全部齐全。
  • 倒置砂轮涂抹配方:去蜡/去锈/去皮 × 全注册方块生成完备,配方 ID 无冲突(已核对生成 JSON 与目标分支);inheritSmearBlockState 解决"涂抹不保留方块状态"的经典问题。
  • 配方无冲突:新增 crate(木板+树脂)与 large_crate(去皮原木多方块)配方在 dev/1.21/1.6 上均无同 ID 配方(已实际核对目标分支)。
  • StorageScreen 渲染层级修复(高亮垫底、鼠标物品 z+100、tooltip 最上层)与战利品表 main-part 条件(只主部件掉落)都处理到位。

📋 声称验证表

声称 状态 对应文件
能质逆变器 (#4338) MassEnergyInverterBlock/BlockEntity, MassInjectBehavior(临近砧座时注入量 ×2), ModBlocks/ModBlockEntities, ProceduralProcessRecipeLoader, MultiBlockRecipeLoader, FunctionalBlocks, JEI, lang
新方块涂抹配方 (#4324) BlockSmearRecipeLoader(去蜡/去锈/去皮 × 全注册方块,160+ 生成配方+advancement), InWorldRecipeEventListener.inheritSmearBlockState, BlockSmearCategory 门方块渲染适配
修复存储系统 bug (#4403/#4408) 战利品表补 copy_components(修复拆容器丢数据), playerWillDestroy 重写, recheckOpeners 重构, BreakBlockEventListener.preventCrateBreak, CapabilitiesEventListener 只读 IItemHandler
优化存储系统 StorageServerStub 撤销系统, StorageScreen 交互增强, StorageTooltip/ClientStorageTooltip 使用量显示, ReadOnlyItemHandlerWrapper

🧪 测试建议

被测目标 推荐测试场景 优先级
ShulkerContainerBlock.playerWillDestroy 空/非空 × 生存/创造 × 主部件/子部件拆除,确认物品数据保留与 clearId 行为 🔴
StorageServerStub.undo 库存满/半满时撤销多物品移动,确认 addItem 失败回插无丢失 🟡
InWorldRecipeEventListener.inheritSmearBlockState 去皮原木朝向、门去蜡后 OPEN/HALF 状态保持 🟡
MassEnergyInverterBlockEntity.tick 电网供电/断电切换时注入停止/恢复 🟢
BreakBlockEventListener.preventCrateBreak 恰好 1000 / 1001 件边界、潜行绕过 🟢

结论: REQUEST_CHANGES — 核心功能与修复质量高,但生成 lang 文件过期(4 个新 key 缺失,用户可见)需重新跑 datagen 后合并;乱码注释与若干存储清理问题建议一并处理。


由 Hermes Agent 审查(已在 PR 分支与 dev/1.21/1.6 上交叉验证关键 API 与生成文件)

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'minecraft-mod-pr-review' (1 replacement).

Pigeon_Nian added 2 commits August 15, 2026 17:04
- 移除未使用的pickupAllSlot变量
- 在tick方法中同步更新carried物品堆
- 修正鼠标点击处理逻辑,增加对空槽位且carried不空时的处理
- 优化双击判断逻辑,增加按钮参数以区分不同点击事件
- 解决双击物品时快速拾取功能的状态管理和触发条件
- 调整handleInventoryMouseClick调用,确保正确传递槽位和点击类型
- 重构快速操作相关代码,提升代码清晰度和可维护性
- 当拾取物品为空时,将 lastClickTime 重置为 0
- 解决连续点击时间未清除导致的异常行为
- 优化玩家界面交互逻辑响应
- 改善快速制作状态的管理逻辑
@Gugle2308

Copy link
Copy Markdown
Collaborator

所有关键文件已审查完毕。整理最终报告。

代码审查摘要 — PR #4399

操作: synchronize
范围: 221 个文件 (38 Java, 184 新增, 0 删除) / 8475 行 diff
分支: inverter/1.21/1.6 → dev/1.21/1.6

概览

PR 三个主要部分:① 新增能质逆变器(Mass Energy Inverter)方块及配方;② 方块涂抹配方系统扩展(倒置砂轮去蜡/去锈/去皮,共 88 个新配方);③ 存储系统大优化(Ctrl+Z 撤销、Shift 拖拽批量快速移动、Alt 同类归仓、创造批量克隆放置、只读 ItemHandler、大箱子防误拆、存储 tooltip 用量显示)。

🔴 关键

  • MassEnergyInverterBlockEntity.java(新)— 每 tick 注入 5 质量,数值与网络同步双重问题

    • MASS_PER_TICK = 5 vs SpaceOvercompressorBlockEntity.NEUTRONIUM_INGOT_MASS = 10_000_000:需要 200 万 tick(约 27.8 小时)才产出 1 个中子锭,且持续消耗 1024 power/tick。相对铁砧注入配方(最大 25000 质量/物品、翻倍后一次可达千万级)这个被动注入量在数值上几乎无意义——请确认是否为笔误(如应为 5_000_000)或有其他设计意图。
    • 每 tick 对每个水平相邻压缩机调用 injectMass(5) → 触发 setChanged()sendBlockUpdated(),即每 tick 每台压缩机 1 个区块更新包(4 台压缩机时 80 包/秒),且注入量远低于产出阈值时也照发。建议节流(如每 N tick 注入一次,或仅当 storedMass 跨过产出阈值时才 sendBlockUpdated)。
  • rpc/StorageServerStub.java(改)— undoingGroup 状态泄漏

    • beginUndoGroup()undoingGroup = true,但只有 endUndoGroup() 能复位。客户端在 mouseReleased 才调用 endUndoGroup——若玩家 Shift 拖拽后直接按 ESC 关闭界面(不触发 mouseReleased),undoingGroup 永久卡 true,此后所有 deposit/移动都合并进永不 push 的 undoGroup,Ctrl+Z 撤销功能失效,直到下次 begin/end 才恢复。建议在 Screen 关闭路径补 endUndoGroup,或给 undoingGroup 加超时/会话级保护。

⚠️ 警告

  • api/itemhandler/ReadOnlyItemHandlerWrapper.java(新)— 注释乱码:第 5 行注释实际字节为 /// ??? IItemHandler ????????????????(中文经错误编码落盘成 ?)。建议改为英文注释或删除。
  • block/entity/storage/ShulkerContainerBlockEntity.java(改)— openers 清理逻辑行为变化:原实现用 hasContainerOpen() 过滤(仅保留正在打开 GUI 的玩家),新 removeIf 移除了该检查——玩家关闭 GUI 后站在范围内仍被计入 openers,箱子可能保持"打开"渲染状态直至离开交互范围。若为有意放宽请忽略,否则建议保留 hasContainerOpen() 判断。
  • block/entity/storage/StorageBlockEntity.java(改)— dropContents 实体爆炸风险:对满容 LARGE_CRATE(65536 空间)破坏时 popResource 按 64 一组拆分,单箱可产生上千个掉落物实体,服务器可能瞬时卡顿/冲击实体上限。建议分批或限制单次掉落实体数。
  • block/container/storage/ShulkerContainerBlock.java(改)— creative 破坏空容器不掉落方块empty → clearId() 后无掉落生成逻辑(getDrops 仅在 creative && !empty 分支),creative 玩家破坏空 Shulker Container 方块会直接消失。与 Crate(内容掉落)行为不一致,确认是否有意。
  • anvil/MassInjectBehavior.java(改)— 翻倍加成不校验电网状态:只要压缩机旁存在逆变器方块即质量 ×2(无论逆变器是否通电),而逆变器自身的 tick 注入要求 isGridWorking()。两处判定标准不一致,若翻倍加成也应以电网工作为前提,需补充检查。

💡 建议

  • data/lang/ScreenTooltipLang.java / en_us.json / en_ud.json — 死键tooltip.anvilcraft.item.crate.large_crate.shulker_container 三个键(含 en_ud 翻转文本)未被任何代码引用——ItemTooltipManager 用的是硬编码英文字符串。冗余键会被 Crowdin 翻译浪费,建议删除或让 ItemTooltipManager 改用 translatable。
  • client/gui/screen/StorageScreen.java(改)— 双击条件冗余if (button == 0 && this.isDoubleClick(slot, button) && slot == lastClickedInventorySlot)lastClickedInventorySlot 刚在上方赋值,slot == lastClickedInventorySlot 恒为 true,属死条件,可移除。
  • StorageScreen.java — mouseReleased 双击执行条件PICKUP_ALL 要求释放时鼠标仍停留在原槽位,比 vanilla 双击更严格,快速双击后轻微移动鼠标会丢失 PICKUP_ALL,建议放宽为仅校验按钮/时间。
  • rpc/StorageServerStub.javaundo()getStackSpace 未考虑同类型跨槽合并优化emptySlots 估算与 player.addItem 实际占用可能偏差(偏保守,安全但可能少退),非阻塞。

🟢 看起来不错

  • 电网接入完整:ServerBlockEntityEventListener 自动发现 IPowerComponent BE 注册/注销,逆变器无需额外接线 ✅
  • 新增 RPC 全部带 StorageAccessValidator/StorageUsageValidator 校验 ✅
  • 与 base 分支 API 完全匹配(StorageView.insert(ItemStack,int)extract(int,int) 等,已用 git show FETCH_HEAD 交叉验证)✅
  • 破坏掉落链路闭环:Crate 内容掉落 + Storages.remove,Shulker 用 CopyComponentsFunction loot 保留 STORAGE 组件,锤子/普通挖掘路径顺序调整正确(先 playerWillDestroydropSilkTouch)✅
  • 方块涂抹配方的状态继承(inheritSmearBlockState)补上了砧库不继承输入方块的缺陷,原木去皮朝向可保留 ✅
  • en_us/en_ud 键完全一致、配方 JSON 结构正确、WIP 显示模型齐备 ✅
  • 大箱子防误拆(Shift 保护 + 锤子拒绝)与 tooltip 文案("Breaking it drops the contents")自洽 ✅

📋 声称验证表

声称 状态 对应文件
能质逆变器 MassEnergyInverterBlock/BlockEntity, ModBlocks, ProceduralProcessRecipeLoader, assets
方块涂抹配方(去蜡/去锈/去皮) BlockSmearRecipeLoader, InWorldRecipeEventListener, 88 个 recipe/advancement JSON
存储系统优化(撤销/批量移动/只读保护) StorageScreen, StorageClientStub/ServerStub, CapabilitiesEventListener, BreakBlockEventListener
resolved #4338 #4324 #4403 #4408 ⚠️ 无法直接核对 issue 内容;相关修复(破坏掉落、锤子保护、RPC 参数)均已在 diff 中找到实现

🧪 测试建议

被测目标 推荐测试场景 优先级
StorageServerStub.undo() 背包满/空、多物品类型混合、同类型跨槽合并、撤销后再次撤销、storage 中被提取后放回 🔴
StorageServerStub.quickMoveToStorage 重复槽位去重、超过 MAX_SYNC_SLOTS 上限、Shift 拖拽 + ESC 中断后 undo 可用性 🔴
ShulkerContainerBlock.playerWillDestroy creative/survival × 空/非空 × 主部件/子部件破坏,验证掉落物与 STORAGE 引用 🟡
MassEnergyInverterBlockEntity.tick 电网工作/断开、多压缩机环绕、注入后 storedMass 网络同步频率 🟡
StorageScreen 双击/快速操作 双击 PICKUP_ALL、Alt 同类归仓、创造中键批量 clonePut、撤销组 🟡
InWorldRecipeEventListener.inheritSmearBlockState 带朝向原木去皮、氧化铜去锈后状态保持、无属性方块 🟢

结论: COMMENT — 整体质量良好,API 匹配、注册完整、破坏掉落链路闭环。建议合并前修复:逆变器 MASS_PER_TICK 数值确认 + 每 tick 网络同步节流、undoingGroup ESC 中断泄漏、乱码注释。其余为可后续跟进的行为变化与优化项。


由 Hermes Agent 审查

@Gugle2308

Copy link
Copy Markdown
Collaborator

审查完成。以下是完整的代码审查意见。


代码审查摘要 — PR #4399

操作: synchronize
范围: 221 个文件(38 Java,184 新增,0 删除)/ 8478 行 diff
分支: inverter/1.21/1.6dev/1.21/1.6

功能映射概览

声称 状态 对应文件
resolved #4338 能质逆变器 MassEnergyInverterBlock/BlockEntity, MassInjectBehavior(质量翻倍), ModBlocks/ModBlockEntities, procedural 配方, CFA 多方块结构加入 F=inverter
resolved #4324 方块涂抹配方 BlockSmearRecipeLoader(倒置砂轮 去蜡/去锈/去皮 全量生成), InWorldRecipeEventListener.inheritSmearBlockState, BlockSmearCategory
fixed #4403 破坏板条箱丢失内容物 StorageBlockEntity.dropContents + clearId, CrateBlock/LargeCrateBlock.playerWillDestroy, BreakBlockEventListener.preventCrateBreak(>1000 需 Shift), AnvilHammerItem 锤子拒绝
resolved #4408 存储 GUI 物品栏优化 StorageScreen 重构(Shift 拖拽批量快速移动、Ctrl+Z 撤销、Alt 同类移动、双击拾取全部、中键批量克隆), StorageServerStub undo 系统, StorageTooltip/ClientStorageTooltip, ReadOnlyItemHandlerWrapper

所有 4 个 issue 的声明都在 diff 中找到对应实现。JEI 新增 ShulkerContainerUpgradeCategory(6 个下界合金块 + 空间超压器,与既有 Upgrade2ShulkerContainerBehavior 的 count < 6 门槛一致 ✅)。


🔴 关键问题

未发现编译级或数据丢失级的阻断问题。以下问题建议在合并前修复:

⚠️ 警告

  1. StorageServerStub.undo() — 撤销记录在操作成功前就被弹出

    UndoRecord record = stub.undoRecords.pollFirst();   // ← 先弹出
    if (record == null) return new DepositResult(false);
    ...
    int extract = Math.min(fit, countInStorage(view, resource, fit));
    if (extract <= 0) continue;   // ← 存储里已没有这些物品时

    当存储内容已被取走/变化导致撤销实际失败时(changed=false),记录已从 deque 永久丢失,玩家按 Ctrl+Z 无反应且无法再撤销。建议改为 peekFirst() + 仅在 changedpollFirst()

  2. StorageBlockEntity.dropContents() — 超量实体喷射风险([Bug] 破坏板条箱等存储系列方块丢失内容物 #4403 修复的副作用)
    大板条箱满仓 65536 时,破坏会按每 64 个 spawn 一个物品实体,非堆叠物品(如工具)每件一个实体——单格可能瞬间生成上千实体,触发实体上限/卡顿甚至物品被清。虽然 >1000 的 Shift 守卫能挡误触,但故意拆大箱子仍会爆炸式掉物。且爆炸/活塞破坏路径不会调用 playerWillDestroy——存储仍会滞留注册表变成孤儿([Bug] 破坏板条箱等存储系列方块丢失内容物 #4403 只修了玩家破坏路径)。建议:破坏时限制掉物速率/分批,或给 LootTable 挂 copy_components 让箱子以物品形态保留存储(与潜影集装箱一致)。

  3. MassEnergyInverterBlockEntity.tick() — 每 tick 无条件 level.getBlockEntity(neighborPos)
    位于区块边界的逆变器会触发同步区块加载(C2ME 环境下有死锁风险,本仓库 CfaInterfaceScanner 已用 level.isLoaded(pos) 防护)。建议加 level.isLoaded(neighborPos) 前置检查或 getChunkNow() 模式。4 个方向每 tick 调用,成本也不低。

  4. AnvilHammerItem.breakBlock() 的大板条箱守卫可绕过

    level.getBlockEntity(pos) instanceof StorageBlockEntity storage

    大型板条箱的 BE 只在主方块上——锤子敲非主方块子部件getBlockEntity(pos) 为 null,>1000 守卫被跳过,直接触发 dropContents 全量掉物。建议与 LargeCrateBlock 一样先 getMainPartPos 再取 BE。

  5. ReadOnlyItemHandlerWrapper.java 第 12 行注释是乱码

    /// ??? IItemHandler ????????????????

    源码里是字面 ASCII ?(编码转换损坏,原意应为中文注释)。不报错但应清理/重写。

  6. ShulkerContainerBlockEntity.recheckOpeners() 行为收紧
    旧代码会重建「范围内且开着容器的玩家」集合(自愈);新代码只剔除死亡/离线/超范围的玩家,不再剔除在范围内但已关闭容器的玩家,且不会重新补入漏登记的开启者。正常关闭路径(setOpen(false))会移除,但一旦关闭路径未触发(如范围内传送/GUI 关闭异常),isOwnContainer 判定会残留导致容器保持 OPENED 状态。建议在移除条件中补上 !player.hasContainerOpen()

💡 建议

  • 撤销覆盖不一致deposit / Shift 拖拽 / Alt 同类移动有撤销记录,但 Shift+左键(手上非空时走 interact() QUICK_MOVE_TO_STORAGE)和 take()(取出)不记录——Ctrl+Z 对这些操作无反应。可统一走 recordUndo 或至少在 UI 上区分。
  • 中键拖拽(button==2)克隆quickCraftToSlots 会把 button 直接作为 ClickType.QUICK_CRAFT 的按钮参数发给服务端。原版 QUICK_CRAFT 的按钮语义是 0=开始/1=加槽/2=结束,中键拖拽用法较特殊,建议实机验证服务端 InventoryMenu 对 button==2 的处理符合预期(该路径只在创造模式生效,风险有限)。
  • ItemTooltipManager.STORAGE_USAGE 缓存:按 storage UUID 无上限增长,长会话多箱子会缓慢泄漏少量内存;可加 LRU 或复用 STORAGE_USAGE_PENDING 做清理。
  • undo()emptySlots 估算与 addItem 实际落位:计数逻辑经推演自洽(addItem 只填同类型栈或空格子),但若未来物品有特殊 canMerge 行为需留意。
  • celestial_forging_anvil 多方块结构变更:中间层 "CCC""CFC" 新增 F=mass_energy_inverter,是既有结构的破坏性变更——已搭建的 CFA 需重建,建议在 PR 描述或更新日志中注明。

🟢 看起来不错

  • inheritSmearBlockState 属性继承:泛型 Property<T> 复制带类型安全 cast,原木朝向/门 half/facing 都能正确保留,同时顺带修复了旧蜂巢涂抹配方不继承方块状态的隐患。
  • 撤销系统整体设计ArrayDeque + MAX_UNDO_RECORDS=4 上限、undoGroup 分组合并、recordUndo/pushUndo 分离,逻辑清晰;undo 的库存空间预估算(stackSpace + emptySlots×maxStack)经过多条目推演保持一致。
  • 存储保护分层:>1000 的 Shift 守卫(BreakEvent 层)+ 锤子拒绝 + 潜影集装箱空仓 clearId()(避免掉落物品带失效 storage 引用)+ 掉落物带 copy_components loot 表,设计完整。
  • Shulker/Hyperdimension 只读 ItemHandlerReadOnlyItemHandlerWrapper 拒绝 insert/extract,配合 isItemValid=false,堵住管道抽物品的漏洞,符合潜影箱定位。
  • 渲染/交互细节:StorageScreen 高亮先画底层、手持物品 z=100 置顶、tooltip 最后绘制;JEI 门渲染(下半扇下移一格)处理正确;en_ud/en_us/lang Java 生成源三方一致。
  • 无 TODO/FIXME/调试残留、无硬编码凭据、无 ghost 文件、EOF 缺换行仅存在于生成 JSON(datagen 常态)。

📋 声明验证表

声称 状态 对应文件
Added Mass Energy Inverter MassEnergyInverterBlock(+BE), MassInjectBehavior, ModBlocks/ModBlockEntities, ProceduralProcessRecipeLoader, 生成 JSON
More block smear recipes BlockSmearRecipeLoader(倒置砂轮 × 全部去蜡/去锈/去皮块), InWorldRecipeEventListener, BlockSmearCategory, 99 个配方 JSON
优化了存储系统 StorageScreen/StorageServerStub undo + 批量操作, recheckOpeners 优化, 工具提示, 只读能力包装
resolved #4338 / #4324 / fixed #4403 / resolved #4408 见上方功能映射表

结论: COMMENT — 功能实现完整、issue 声明全部落实,撤销系统与配方生成质量不错;但建议先处理 ⚠️ 中的 undo 记录提前弹出#1)与 dropContents 实体爆炸风险#2),并修复锤子守卫绕过(#4)与乱码注释(#5)后再合并。其余为可选优化。

🧪 测试建议

被测目标 推荐测试场景 优先级
StorageServerStub.undo() 存储物品被取走后再撤销(记录应保留);库存满时撤销;非堆叠物品撤销 🔴
StorageBlockEntity.dropContents() 满仓大板条箱破坏时的实体数量/服务器 TPS;爆炸破坏路径 🔴
StorageScreen 双击拾取 双击拾取全部与单击拾取互不干扰;双击后 250ms 冷却 🟡
MassEnergyInverterBlockEntity.tick 区块边界放置时的行为;断电解网后停止注入 🟡
方块涂抹 倒置砂轮去蜡铜门/去皮原木的 facing/half/axis 属性保留 🟡
ShulkerContainerBlockEntity.recheckOpeners 玩家范围内关闭容器后 OPENED 状态是否正确复位 🟡

由 Hermes Agent 审查

⚠️ File-mutation verifier: 1 file(s) were NOT modified this turn despite any wording above that may suggest otherwise. Run git status or read_file to confirm.
/tmp/extract.sh — [write_file] Write denied: '/tmp/extract.sh' is a protected system/credential file.

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched references/webhook-session-tooling.md in skill 'minecraft-mod-pr-review' (1 replacement). · Patched SKILL.md in skill 'minecraft-mod-pr-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'anvilcraft-power-storage-review' (1 replacement).

- 将悬浮提示的显示判断逻辑移动到渲染高亮之后
- 确保只有在物品不为空且鼠标在区域内时才渲染悬浮提示
- 优化代码结构提高可读性和逻辑清晰度
@PigeonNian
PigeonNian marked this pull request as ready for review August 15, 2026 09:37
- 将局部变量quick声明为final,保证其不可变性
- 优化双击检测条件,使逻辑更清晰
- 修正代码格式提升代码可读性
@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Dangerous command requires approval:

cd /tmp && echo "=== Storages cleanup policy ===" && curl -sL "https://raw.githubusercontent.com/Anvil-Dev/AnvilCraft/dev/1.21/1.6/src/main/java/dev/dubhe/anvilcraft/saved/storage/Storages.java" -o St...

Reason: Security scan — [HIGH] Pipe to interpreter: curl | python3: Command pipes output from 'curl' directly to interpreter 'python3'. Downloaded content will be executed without inspection.
Safer: tirith run https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4338 — or: vet https://api.github.com/repos/Anvil-Dev/AnvilCraft/issues/4338 (https://getvet.sh); script execution via -e/-c flag

Reply /approve to execute, /approve session to approve this pattern for the session, /approve always to approve permanently, or /deny to cancel.

@QiuShui1012
QiuShui1012 merged commit 8a2da46 into Anvil-Dev:dev/1.21/1.6 Aug 15, 2026
2 checks passed
@Gugle2308

Copy link
Copy Markdown
Collaborator

PR #4399 已确认 closed 且已合并merged_at = closed_at = 2026-08-15T09:46:36Z,merged: true)。

按审查约束第 1 条(action 为 closed → stop here,不发布评论),此 PR 跳过审查,不输出审查意见。

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Iteration budget exhausted (90/90) — asking model to summarise

@Gugle2308

Copy link
Copy Markdown
Collaborator

I reached the maximum iterations (90) but couldn't summarize. Error:

<title>504 Gateway Time-out</title>

504 Gateway Time-out


openresty

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'anvilcraft-power-storage-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

I now have a complete picture. Let me compile the final review.


代码审查摘要 — PR #4399(synchronize: Mass Energy Inverter + 方块涂抹配方 + 存储系统修复)

结论: 建议合并(无阻塞性问题),但有 5 条警告与若干建议。审查范围:222 个文件(184 新增 / 0 删除),其中 Java 39 个文件约 +1500 行;其余为生成资源(block_smear 配方、advancement、lang、loot)。


🆕 新功能一:能质逆变器(Mass Energy Inverter)

  1. MassInjectBehavior 双倍注入 + BE 被动注入 ✅ — 铁砧注入时若超压器水平相邻逆变器则质量 ×2;逆变器 BE 在电网工作(1024 FE/t)时每 tick 向相邻超压器注入 5 mass。isGridWorking() 默认实现用 Optional.map(...).orElse(false) 处理了 null grid,tick 安全。level.getBlockEntity() 不会跨区块强制加载(未加载返回 null),安全。
  2. 注册链完整 ✅ — ModBlocks.MASS_ENERGY_INVERTER(blockstate/model item/loot/mineable tag/creative tab)+ ModBlockEntities.MASS_ENERGY_INVERTER(validBlocks + createBlockEntity)+ 程序化配方(激光接收器 → WIP → 逆变器)+ celestial_forging_anvil 多方块结构加入逆变器作为材料。BE 无持久化字段(grid 为运行时态),无需 saveAdditional ✅。
  3. 💡 建议displayedModels 引用的 mass_energy_inverter_wip/_2/_3 模型不在本 PR 中。我核对了现有配方(如 ancient_debris_wip)在仓库中同样不存在对应模型文件,属代码库既有约定(运行期解析),非本 PR 引入问题,仅提醒确认。

🆕 新功能二:方块涂抹配方(倒置砂轮打磨)

  1. 配方生成器正确性 ✅ — 遍历注册表,WAX_OFF_BY_BLOCK / WeatheringCopper.getPrevious / AxeItem.getAxeStrippingState 三类映射生成去蜡/去锈/去皮配方;配方 ID 用 result.path + suffix,每种结果唯一对应一个输入,无 ID 冲突;与生成的 72+ recipe/advancement JSON 一一对应 ✅。
  2. inheritSmearBlockState 属性继承 ✅ — 我核对了 BlockSmearRecipe 默认偏移:blockInputOffset=(0,-1,0)blockOutputOffset=(0,-2,0),输入竖向堆叠。事件处理器用 inputOffset.subtract(0, inputs.size()-1, 0) 定位到底部被处理方块(2 输入时即 y-2),与配方布局一致;原蜜脾打蜡配方也走同一路径且同样正确。门/铜格栅的 WATERLOGGED、AXIS、HALF 等属性可正确继承 ✅。
  3. 门(双格方块) ⚠️ 建议人工确认一次:配方只替换匹配位置的单格,双格门被打磨时仅一格被替换成结果门、另一格保持原方块(新代码比旧代码好——至少 HALF 属性被继承了——但混合门外观仍可能异常)。JEI 渲染层已专门处理门(renderDoorBlock 上下半扇拼接),说明作者测试过门路径,请确认实测结果。

🔧 存储系统修复(resolved #4338 / #4324 / #4403 / #4408,无法拉取 issue 内容,以下为按 diff 推断的映射)

  1. 方块破坏/掉落生命周期重构 ✅ — StorageBlockEntity.dropContents()(掉落全部内容 + 从全局注册表 remove storage)、clearId()、Crate/LargeCrate playerWillDestroy 改为 dropContents、Shulker/Hyperdimension 自定义 loot(仅主部件 + copy STORAGE component)——我核对了 crate 的 loot 表含 storage copy(打破掉普通板条箱 ✅)、shulker 的 loot 表含 copy_components(打破掉带 storage 引用的容器 ✅),与 tooltip 文案一致。
  2. ⚠️ 空潜影集装箱打破后 storage 泄漏ShulkerContainerBlock.playerWillDestroy:空容器只 clearId()Storages.get().remove(id)Storages 是 SavedData + HashMap,无 GC——每次打破一个被清空的潜影箱都会在存档里永久留下一个空 storage 条目(存档膨胀 + 内存累积)。而 CrateBlock 路径是 remove 的。建议空容器同时 remove。
  3. ⚠️ 创造模式打破空潜影集装箱物品直接消失 — 新逻辑:空 + 创造 → clearId 后无任何掉落(旧代码会掉落带引用的容器)。若是有意为之(避免死引用物品)请忽略,否则建议空容器也掉落一个无 STORAGE 引用的普通容器。
  4. StorageScreen 交互重构 ✅ — shift 拖拽批量移动(快照去重 + tick 刷新)、双击拾取全部(修复了旧版 pickupAllSlot 只在相同 slot 生效的 bug,现在需要同 slot+同按键+250ms)、Alt+点击移动同类物品、创造中键拖拽克隆放入、点击屏幕外丢出物品(-999 PICKUP)、渲染 z 序修复。逻辑自洽。
  5. 撤销系统(Ctrl+Z,最多 4 条记录) ✅ 整体正确 — 记录 (ItemStack, count) 映射,按资源回提(extractByResource + isSameItemSameComponents),背包满时重新塞回存储;deposit/quickMove/moveSame 均接入。⚠️ 注意两点:
    • undoGroup 悬挂:拖拽中按 Esc 关屏,endUndoGroup 永不发送 → 服务端 undoingGroup 卡 true,后续移动的撤销记录被吞且 undoGroup 持续累积(直到下次 beginUndoGroup 清空或登出 STUBS.clear())。建议 StorageScreen.onClose 补发 endUndoGroup,或服务端加防御重置。
    • 槽位上界缺失quickMoveToStorage 只查 slot < 0,未查 slot >= Inventory.INVENTORY_SIZEmoveSameToStoragemoveInventoryStackToStorage 都有上界检查)——恶意客户端可发超大槽位导致 getItem 越界。应补上界校验。
  6. 只读 ItemHandler ✅ — Shulker/Hyperdimension 对自动化管道暴露 ReadOnlyItemHandlerWrapper(insert 原样返回、extract 空、isItemValid false),防止管道搬空容器,设计合理。
  7. 打破保护(>1000 物品需 Shift) ✅ — preventCrateBreak(BreakEvent)正确路由 LargeCrate 主部件;AnvilHammerItem 守卫 + 工具提示完整。💡 小建议:AnvilHammerItem 的守卫直接查 level.getBlockEntity(pos),对 LargeCrate 子部件未走 getMainPartPos,与 BreakEvent 路径不一致——若子部件 BE 未持有 storage id 则守卫会静默失效(内容仍会正确掉落,只是不拦截)。建议统一。
  8. ShulkerContainerBlockEntity.recheckOpeners 重写 ✅ 逻辑等价于旧实现(保留范围内存活玩家),但注意不再检查 hasContainerOpen()——关闭 GUI 但站在范围内的玩家不会被移除(正常关闭路径由 onPlayerClose 处理,此方法只是兜底),行为变更请确认符合预期。
  9. tooltip 用量显示 ✅ — ItemTooltipManager 异步 RPC 拉取 storage 用量 + 2s 节流 + pending 去重 + StorageTooltip/ClientStorageTooltip 渲染(最多 9 种图标)。💡 建议:STORAGE_USAGE/STORAGE_USAGE_TIMES 静态缓存永不淘汰,长时间游戏悬停不同容器会无限增长,建议加 LRU/上限。

⚠️ 代码质量

  1. ReadOnlyItemHandlerWrapper.java 注释乱码 — 第 3 行 /// ??? IItemHandler ???????????????? 是编码损坏的中文注释(全 PR 唯一一处乱码),建议重写。
  2. 💡 183/184 个新生成 JSON 缺 EOF 换行(含 blockstate、全部 recipe、advancement、loot)— 大规模缺换行提示数据生成器输出问题,建议修复生成器。

统计

指标
文件数 222(184 新增 / 0 删除)
Java 文件 39(+1500 行)
生成资源 183
新配方 block_smear 去蜡/去锈/去皮 72+、crate、large_crate 多方块、mass_energy_inverter 程序化

核心建议:修复空潜影箱 storage 泄漏(#8)、undoGroup 悬挂(#11a)、quickMoveToStorage 上界(#11b)、乱码注释(#16);其余为建议项。

@Gugle2308

Copy link
Copy Markdown
Collaborator

⚠️ Iteration budget exhausted (90/90) — asking model to summarise

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'anvilcraft-power-storage-review' (1 replacement).

@Gugle2308

Copy link
Copy Markdown
Collaborator

I reached the maximum iterations (90) but couldn't summarize. Error:

<title>504 Gateway Time-out</title>

504 Gateway Time-out


openresty

@Gugle2308

Copy link
Copy Markdown
Collaborator

💾 Self-improvement review: Patched SKILL.md in skill 'anvilcraft-power-storage-review' (1 replacement).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants